#region using directives

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Windows.Forms;
using Timer=System.Windows.Forms.Timer;

#endregion

namespace ClientForms
{
    /// <summary>
    /// Summary description for SplashForm.
    /// </summary>
    public class SplashForm : Form
    {
        //this is the variable that determines the fade increment for opacity
        private static double _fade;

        //this value will be used as the timer tick for the fadetimer
        private static int _fadetimerinterval;
        private static bool _showDialogBox = false;

        //the holder for status text that's to be displayed at the bottom of the splash screen

        //a reference to the form itself
        private static SplashForm _splashForm = null;

        //label for the starter kit text

        //used for multi threading
        private static Thread _splashthread = null;
        private static int _timeout;
        private static string statusText = null;

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private Container components = null;

        private Timer fadetimer;
        private Label label1;
        private Timer timer;

        //a flag to determine if the form has a dialog box showing


        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeout">
        /// the number of ms before the form automatically closes.  Pass in 0 to disable this.
        /// </param>
        public SplashForm(int timeout)
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            timer = new Timer();


            //don't start the timer is 0 passed in
            if (timeout > 0)
            {
                timer.Start();
                timer.Interval = timeout;
                timer.Tick += new EventHandler(closeSplash);
            }

            fadetimer = new Timer();

            fadetimer.Interval = _fadetimerinterval;


            fadetimer.Tick += new EventHandler(fadeTimerHandler);
            fadetimer.Start();


            Opacity = 0;

            TopLevel = true;

            ShowInTaskbar = false;
            FormBorderStyle = FormBorderStyle.None;
            StartPosition = FormStartPosition.CenterScreen;
        }

        /// <summary>
        /// set the private variable to the status text
        /// </summary>
        /// <param name="text">The status text to be displayed.</param>
        public static string StatusText
        {
            set { statusText = value; }
            get { return statusText; }
        }

        /// <summary>
        /// return a reference of the splash form
        /// </summary>
        public static Form FormRef
        {
            get { return _splashForm; }
        }

        /// <summary>
        /// This is used to show the splash form using a seperate thread.  
        /// This makes it possible to load in the background on the main thread
        /// and update your user with status on the splash screen
        /// </summary>
        /// <param name="timeout">The number of ms before the form automatically closes.  Pass in 0 to disable this and close manually.</param>
        /// <param name="fade">A  value representing the change in opacity to make for each tick of the faderTimer.</param>
        /// <param name="fadertimerinterval">The interval in ms for the fader timer.  Each tick of the fader timer changes the opacity by the amount specified in "fade"</param>
        public static void Showasyncsplash(int timeout, double fade, int fadertimerinterval)
        {
            _timeout = timeout;
            _fade = fade;
            _fadetimerinterval = fadertimerinterval;

            //make sure we only launch the form once
            if (_splashForm == null)
            {
                _splashthread = new Thread(new ThreadStart(ShowSplash));
                _splashthread.IsBackground = true;
                _splashthread.SetApartmentState(ApartmentState.STA);
                _splashthread.Start();
            }
            else
            {
                return;
            }
        }

        public static void ShowDialogBox(string message)
        {
            _showDialogBox = true;
            MessageBox.Show(message);
            _showDialogBox = false;
            closeAsyncSplash();
        }

        public static void closeAsyncSplash()
        {
            if (!_showDialogBox)
            {
                if (_splashForm != null && _splashForm.IsDisposed == false && _fade > 0)
                {
                    //if the timer expires then reverse the fade constant
                    _fade = -_fade;
                }

                _splashthread = null;
                _splashForm = null;
            }
        }

        /// <summary>
        /// shoow the splash form on the new thread
        /// </summary>
        public static void ShowSplash()
        {
            _splashForm = new SplashForm(_timeout);

            Application.Run(_splashForm);
        }

        /// <summary>
        /// Override the OnPaint event to draw the background
        /// </summary>
        /// <param name="pea">The OnPaint event arguments</param>
        protected override void OnPaint(PaintEventArgs pea)
        {
            DrawSplashFooterText(statusText, pea.Graphics, ClientSize.Width, ClientSize.Height);
        }

        /// <summary>
        /// draws a gradient text string based on the arguments from the OnPaint event
        /// </summary>
        /// <param name="grfx">grfx from the onpaint event</param>
        /// <param name="cx">form width</param>
        /// <param name="cy">form height</param>
        private static void DrawSplashFooterText(string text, Graphics grfx, int cx, int cy)
        {
            //if there is no text to draw then return
            if (text == null)
            {
                return;
            }

            var font = new Font("Tahoma", 12, FontStyle.Bold);
            ////SizeF sizef = grfx.MeasureString(text, font);
            ////var ptf = new PointF((cx - sizef.Width)/2, (cy + Resource.ccs_logo.Height)/2);
            ////var rectf = new RectangleF(ptf, sizef);
            ////var lgbrush = new LinearGradientBrush(rectf, Color.Red, Color.Orange, LinearGradientMode.ForwardDiagonal);
            ////grfx.DrawString(text, font, lgbrush, ptf);
            font.Dispose();
        }


        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// This is the event handler for the timer.
        /// It closes the splash form and stops the event timer.
        /// </summary>
        /// <param name="myObject">event object</param>
        /// <param name="myEventArgs">Event args</param>
        private void closeSplash(Object myObject, EventArgs myEventArgs)
        {
            timer.Stop();
            Close();
        }

        /// <summary>
        /// This is the event handler for the Fadetimer.
        /// It changes the opacity of the form
        /// </summary>
        /// <param name="myObject">event object</param>
        /// <param name="myEventArgs">Event args</param>
        private void fadeTimerHandler(Object myObject, EventArgs myEventArgs)
        {
            Opacity += _fade;

            if (Opacity <= 0)
            {
                Close();
            }
        }

        /// <summary>
        /// This event catches the splash form closing event, and changes the sign
        /// of the fade constant and cancels the close event.  When the fade constant reaches 0 (completely transparent), the form will
        /// be allowed to close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SplashForm_Closing(object sender, CancelEventArgs e)
        {
            //don't close the form if there is a dialog box showing
            if (_showDialogBox)
            {
                e.Cancel = true;
                return;
            }

            //if the timer expires then reverse the fade constant
            if (_fade > 0)
            {
                _fade = -_fade;
                e.Cancel = true;
            }
        }


        private void SplashForm_Load(object sender, EventArgs e)
        {
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.BackColor = System.Drawing.Color.Transparent;
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.Location = new System.Drawing.Point(136, 205);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(295, 31);
            this.label1.TabIndex = 0;
            this.label1.Text = "Client Cloud Services";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // SplashForm
            // 
            this.BackColor = System.Drawing.Color.Silver;
            this.BackgroundImage = global::ClientForms.Resource.splash;
            this.ClientSize = new System.Drawing.Size(567, 441);
            this.Controls.Add(this.label1);
            this.Name = "SplashForm";
            this.ShowInTaskbar = false;
            this.Text = "Client Coud Services";
            this.Load += new System.EventHandler(this.SplashForm_Load);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.SplashForm_Closing);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion
    }
}